Load all of the throw
data
#load omnibus dataframe
omnibus_df <- read_delim("../data/processed/omnibus/omnibus_raw.csv",
delim = ",",
col_types = cols(.default = col_double(),
type = col_factor(),
ppid = col_factor(),
exp_label = col_factor(),
experiment = col_factor(),
hand = col_factor(),
camera_tilt = col_factor(),
surface_tilt = col_factor(),
target = col_factor(),
test_type = col_factor(),
prior_anim = col_factor(),
baseline_block = col_factor(),
task_type = col_factor(),
surface = col_factor(),
anim_type = col_factor()))
original_exps <- c("rot15_cued_tilt", "rot15_uncued", "tilt_uncued_rot",
"tilt_uncued_norot", "tilt_cued_rot", "tilt_cued_norot")
Visualizing data
(univariate)
test_ppt <- 3
test_df <- omnibus_df %>% filter(ppid == test_ppt)
trial <- 250
trial_df <- filter(test_df, trial_num == trial)
x <- trial_df$flick_velocity_x
y <- trial_df$flick_velocity_y
z <- trial_df$flick_velocity_z
x2 <- trial_df$flick_direction_x
y2 <- trial_df$flick_direction_y
z2 <- trial_df$flick_direction_z
# plot both
plot_ly(x = c(0, x), y = c(0, y), z = c(0, z), type = "scatter3d", mode = "lines") %>%
add_trace(x = c(0, x2), y = c(0, y2), z = c(0, z2), type = "scatter3d", mode = "lines") %>%
layout(scene = list(xaxis = list(title = "x"),
yaxis = list(title = "y"),
zaxis = list(title = "z")))
# note: this is a rotated trial
# plot distribution of error_size
p <- ggplot(omnibus_df, aes(x = error_size)) +
geom_histogram(binwidth = .5) +
theme_minimal() +
theme(text = element_text(size = 11)) +
labs(x = "Error Size (cm)", y = "Count")
p

Original
Experiments
Omnibus Plot for
ANGLES
Note: Blues = Acceleration Perturbations
# rest of the exps
data_per_group <- omnibus_df %>%
filter(exp_label == "original_exps") %>%
group_by(experiment, test_type, trial_num) %>%
summarise(
mean_deviation = mean(throw_deviation),
ci_deviation = vector_confint(throw_deviation),
.groups = "drop"
)
# set up plot
p <- data_per_group %>%
ggplot(
aes(
x = trial_num, y = mean_deviation, colour = experiment
)
) +
theme_classic() +
theme(legend.position = "none") +
labs(
x = "Trial Number",
y = "Throw Angle (°)"
)
# add horizontal lines
p <- p +
geom_hline(
yintercept = c(0, -30), linewidth = 0.4,
colour = "#CCCCCC", linetype = "solid"
) +
geom_hline(
yintercept = c(-15), linewidth = 0.4,
colour = "#CCCCCC", linetype = "dashed"
)
# p <- p +
# scale_y_continuous(
# limits = c(-10, 35),
# breaks = c(0, 15, 30),
# labels = c(0, 15, 30)
# ) +
# scale_x_continuous(
# limits = c(0, 180),
# breaks = c(0, 60, 120, 180),
# labels = c(0, 60, 120, 180)
# )
# set font size to 11
p <- p +
theme(text = element_text(size = 11))
# add confidence intervals and data points
p <- p + geom_ribbon(
aes(
ymin = mean_deviation - ci_deviation,
ymax = mean_deviation + ci_deviation,
fill = experiment
), colour = NA, alpha = 0.3
) + geom_line()
# set colour palette
p <- p + scale_colour_manual(values = c(
pallete_list[["tilt_c"]], pallete_list[["tilt_nc"]],
pallete_list[["rot_c"]], pallete_list[["rot_nc"]],
pallete_list[["rot_15_c"]], pallete_list[["rot_15_nc"]]
)) + scale_fill_manual(values = c(
pallete_list[["tilt_c"]], pallete_list[["tilt_nc"]],
pallete_list[["rot_c"]], pallete_list[["rot_nc"]],
pallete_list[["rot_15_c"]], pallete_list[["rot_15_nc"]]
))
# # save
# if (save_plots) {
# ggsave(
# p,
# filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
# height = 4, width = 6
# )
# }
ggplotly(p)
# p
Trial sets of
interest only
Note: Blues = Acceleration Perturbations
# filter out just the trials of interest
data_per_group <- data_per_group %>%
filter(
test_type != "other"
)
# add a dummy column with repeating sequence
# NOTE: this can't be combined with above since we are using nrow
data_per_group <- data_per_group %>%
mutate(dummy_x = rep(1:(nrow(data_per_group)/6),
length.out = nrow(data_per_group)))
# set up plot
p <- data_per_group %>%
ggplot(
aes(
x = dummy_x, y = mean_deviation, colour = experiment
)
) +
theme_classic() +
theme(legend.position = "none") +
labs(
x = "Trial Number",
y = "Throw Angle (°)"
)
# add horizontal lines
p <- p +
geom_hline(
yintercept = c(0, -30), linewidth = 0.4,
colour = "#CCCCCC", linetype = "solid"
) +
geom_hline(
yintercept = c(-15), linewidth = 0.4,
colour = "#CCCCCC", linetype = "dashed"
)
# add confidence intervals and data points
for (unique_test_type in unique(data_per_group$test_type)) {
# get the data for this block
to_plot_data <- filter(data_per_group, test_type == unique_test_type)
p <- p + geom_ribbon(
data = to_plot_data,
aes(
ymin = mean_deviation - ci_deviation,
ymax = mean_deviation + ci_deviation,
fill = experiment
), colour = NA, alpha = 0.3
) + geom_line(
data = to_plot_data
)
}
# set colour palette
p <- p + scale_colour_manual(values = c(
pallete_list[["tilt_c"]], pallete_list[["tilt_nc"]],
pallete_list[["rot_c"]], pallete_list[["rot_nc"]],
pallete_list[["rot_15_c"]], pallete_list[["rot_15_nc"]]
)) + scale_fill_manual(values = c(
pallete_list[["tilt_c"]], pallete_list[["tilt_nc"]],
pallete_list[["rot_c"]], pallete_list[["rot_nc"]],
pallete_list[["rot_15_c"]], pallete_list[["rot_15_nc"]]
))
ggplotly(p)
Plots for
ERROR
Note: Blues = Acceleration Perturbations
ggplotly(plot_original_learning_curve(omnibus_path))
visible vs non-visible tilt doesn’t affect the 15-degree rotation
condition. But affects all other conditions. So 15-degree rotation
Note: Blues = Acceleration Perturbations
ggplotly(plot_original_rebound(omnibus_path))
Animated Surface
Follow-up
Omnibus Plot for
ANGLES
# isolate animate_surface exp
data_per_group <- omnibus_df %>%
filter(exp_label == "animate_surface") %>%
group_by(prior_anim, block_num, trial_num_in_block, trial_num) %>%
summarise(
mean_deviation = mean(throw_deviation),
ci_deviation = vector_confint(throw_deviation)
)
# set up plot
p <- data_per_group %>%
ggplot(
aes(
x = trial_num, y = mean_deviation,
ymin = mean_deviation - ci_deviation,
ymax = mean_deviation + ci_deviation
)
) +
theme_classic() +
theme(legend.position = "none") +
labs(
x = "Trial Number",
y = "Throw Angle (°)"
)
# add horizontal lines
p <- p +
geom_hline(
yintercept = c(0, -30), linewidth = 0.4,
colour = "#CCCCCC", linetype = "solid"
) +
geom_hline(
yintercept = c(-15), linewidth = 0.4,
colour = "#CCCCCC", linetype = "dashed"
)
# p <- p +
# scale_y_continuous(
# limits = c(-10, 35),
# breaks = c(0, 15, 30),
# labels = c(0, 15, 30)
# ) +
# scale_x_continuous(
# limits = c(0, 180),
# breaks = c(0, 60, 120, 180),
# labels = c(0, 60, 120, 180)
# )
# set font size to 11
p <- p +
theme(text = element_text(size = 11))
# repeat for prior_anim == "half", "full" and "wait"
for (unique_prior_anim in unique(data_per_group$prior_anim)) {
# get the data for this block
to_plot_data <- filter(data_per_group, prior_anim == unique_prior_anim)
# loop through the unique blocks in to_plot_data
for (block in unique(to_plot_data$block_num)) {
# get the data for this block
block_data <- filter(to_plot_data, block_num == block)
# add the data, use the pallete_list to get the colour
p <- p + geom_ribbon(
data = block_data,
aes(fill = prior_anim),
colour = NA, alpha = 0.3
) + geom_line(
data = block_data,
aes(colour = prior_anim))
}
}
# # save
# if (save_plots) {
# ggsave(
# p,
# filename = "../plots/paper_figs/sr_30_training.pdf", device = "pdf",
# height = 4, width = 6
# )
# }
ggplotly(p)
# p
Difference between
half and full animation washout trials
# first, isolate the data
data <- omnibus_df %>%
filter(
exp_label == "animate_surface",
baseline_block == FALSE,
test_type == "washout_anim"
)
data_per_ppt <- data %>%
group_by(ppid, prior_anim, trial_num_in_block) %>%
summarise(
ppt_mean_deviation = median(throw_deviation),
ppt_ci_deviation = vector_confint(throw_deviation),
n = n()
)
data_per_group <- data_per_ppt %>%
group_by(prior_anim, trial_num_in_block) %>%
summarise(
mean_deviation = mean(ppt_mean_deviation),
ci_deviation = vector_confint(ppt_mean_deviation),
n = sum(n)
)
# set up plot
p <- data_per_group %>%
ggplot(
aes(
x = trial_num_in_block, y = mean_deviation,
colour = prior_anim, fill = prior_anim
)
) +
theme_classic() +
theme(legend.position = "none") +
labs(
x = "Trial Number",
y = "Throw Angle (°)"
)
# add horizontal lines
p <- p +
geom_hline(
yintercept = c(0, -30), linewidth = 0.4,
colour = "#CCCCCC", linetype = "solid"
) +
geom_hline(
yintercept = c(-15), linewidth = 0.4,
colour = "#CCCCCC", linetype = "dashed"
)
# add data points
p <- p + geom_beeswarm(
data = data_per_ppt,
aes(y = ppt_mean_deviation,
colour = prior_anim),
size = 1, dodge.width = 0.5
) + geom_ribbon(
aes(
ymin = mean_deviation - ci_deviation,
ymax = mean_deviation + ci_deviation
),
colour = NA, alpha = 0.3
) + geom_line()
ggplotly(p)
Deprecated (Don’t
Run)
Success
manifolds
Without any
tilts
# ggplotly(plot_success_manifold_no_tilt())
plot_success_manifold_no_tilt()
With tilt
present
ggplotly(plot_success_manifold_tilt())
LS0tDQp0aXRsZTogIkJpbGxpYXJkcyBhbmQgVGlsdHMgQW5hbHlzaXMgTm90ZWJvb2siDQphdXRob3I6ICJTaGFuYWF0aGFuYW4gTW9kY2hhbGluZ2FtIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAgICAgICMgY2xlYW4gZW52aXJvbm1lbnQNCg0Kc291cmNlKCIuLi9zcmMvaGVscGVyX2Z1bmNzLlIiKQ0Kc291cmNlKCIuLi9zY3JpcHRzL2ZpZ3VyZV9mdW5jcy5SIikgDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2diZWVzd2FybSkNCmxpYnJhcnkoZXopICNmb3IgQU5PVkFzDQpsaWJyYXJ5KGVmZmVjdHNpemUpICMgZm9yIGV0YS1zcXVhcmVkDQpsaWJyYXJ5KHBsb3RseSkNCg0Kb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtPUYpDQoNCiMgdmFycw0Kb21uaWJ1c19wYXRoIDwtICIuLi9kYXRhL3Byb2Nlc3NlZC9vbW5pYnVzL29tbmlidXNfcmF3LmNzdiINCg0KIyBjb252ZXJ0IHRoZSBhYm92ZSBpbnRvIGEgbGlzdA0KcGFsbGV0ZV9saXN0IDwtIGMoInJvdF9jIiA9ICIjZDQwMDAwIiwNCiAgICAgICAgICAgICAicm90X25jIiA9ICIjZjk5ODJjIiwNCiAgICAgICAgICAgICAidGlsdF9jIiA9ICIjMDc1MDliIiwNCiAgICAgICAgICAgICAidGlsdF9uYyIgPSAiIzVmYjY5NiIsDQogICAgICAgICAgICAgInJvdF8xNV9jIiA9ICIjNzQwMDAwIiwNCiAgICAgICAgICAgICAicm90XzE1X25jIiA9ICIjOTk5ODJjIiwNCiAgICAgICAgICAgICAibm9uZSIgPSAiI2Q0MDAwMCIsDQogICAgICAgICAgICAgImhhbGYiID0gIiM1ZmI2OTYiLA0KICAgICAgICAgICAgICJmdWxsIiA9ICIjMDc1MDliIiwNCiAgICAgICAgICAgICAid2FpdCIgPSAiIzk5OTgyYyIpDQoNCmBgYA0KDQoNCg0KIyMgTG9hZCBhbGwgb2YgdGhlIHRocm93IGRhdGENCg0KDQoNCmBgYHtyfQ0KI2xvYWQgb21uaWJ1cyBkYXRhZnJhbWUNCm9tbmlidXNfZGYgPC0gcmVhZF9kZWxpbSgiLi4vZGF0YS9wcm9jZXNzZWQvb21uaWJ1cy9vbW5pYnVzX3Jhdy5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxpbSA9ICIsIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyguZGVmYXVsdCA9IGNvbF9kb3VibGUoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gY29sX2ZhY3RvcigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHBpZCA9IGNvbF9mYWN0b3IoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cF9sYWJlbCA9IGNvbF9mYWN0b3IoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVyaW1lbnQgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kID0gY29sX2ZhY3RvcigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FtZXJhX3RpbHQgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmYWNlX3RpbHQgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0X3R5cGUgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcl9hbmltID0gY29sX2ZhY3RvcigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWxpbmVfYmxvY2sgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrX3R5cGUgPSBjb2xfZmFjdG9yKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmYWNlID0gY29sX2ZhY3RvcigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbV90eXBlID0gY29sX2ZhY3RvcigpKSkNCg0Kb3JpZ2luYWxfZXhwcyA8LSBjKCJyb3QxNV9jdWVkX3RpbHQiLCAicm90MTVfdW5jdWVkIiwgInRpbHRfdW5jdWVkX3JvdCIsIA0KICAgICAgICAgICAgICAgICAgICJ0aWx0X3VuY3VlZF9ub3JvdCIsICJ0aWx0X2N1ZWRfcm90IiwgInRpbHRfY3VlZF9ub3JvdCIpDQpgYGANCg0KIyBWaXN1YWxpemluZyBkYXRhICh1bml2YXJpYXRlKQ0KDQpgYGB7cn0NCnRlc3RfcHB0IDwtIDMNCg0KdGVzdF9kZiA8LSBvbW5pYnVzX2RmICU+JSBmaWx0ZXIocHBpZCA9PSB0ZXN0X3BwdCkNCg0KDQp0cmlhbCA8LSAyNTANCnRyaWFsX2RmIDwtIGZpbHRlcih0ZXN0X2RmLCB0cmlhbF9udW0gPT0gdHJpYWwpDQoNCnggPC0gdHJpYWxfZGYkZmxpY2tfdmVsb2NpdHlfeA0KeSA8LSB0cmlhbF9kZiRmbGlja192ZWxvY2l0eV95DQp6IDwtIHRyaWFsX2RmJGZsaWNrX3ZlbG9jaXR5X3oNCg0KeDIgPC0gdHJpYWxfZGYkZmxpY2tfZGlyZWN0aW9uX3gNCnkyIDwtIHRyaWFsX2RmJGZsaWNrX2RpcmVjdGlvbl95DQp6MiA8LSB0cmlhbF9kZiRmbGlja19kaXJlY3Rpb25feg0KDQojIHBsb3QgYm90aA0KcGxvdF9seSh4ID0gYygwLCB4KSwgeSA9IGMoMCwgeSksIHogPSBjKDAsIHopLCB0eXBlID0gInNjYXR0ZXIzZCIsIG1vZGUgPSAibGluZXMiKSAlPiUNCiAgYWRkX3RyYWNlKHggPSBjKDAsIHgyKSwgeSA9IGMoMCwgeTIpLCB6ID0gYygwLCB6MiksIHR5cGUgPSAic2NhdHRlcjNkIiwgbW9kZSA9ICJsaW5lcyIpICU+JQ0KICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJ4IiksDQogICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gInkiKSwNCiAgICAgICAgICAgICAgICAgICAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAieiIpKSkNCg0KIyBub3RlOiB0aGlzIGlzIGEgcm90YXRlZCB0cmlhbA0KYGBgDQoNCg0KYGBge3J9DQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBwbG90IGRpc3RyaWJ1dGlvbiBvZiBlcnJvcl9zaXplDQpwIDwtIGdncGxvdChvbW5pYnVzX2RmLCBhZXMoeCA9IGVycm9yX3NpemUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gLjUpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpKSArDQogIGxhYnMoeCA9ICJFcnJvciBTaXplIChjbSkiLCB5ID0gIkNvdW50IikNCg0KcA0KYGBgDQoNCiMgT3JpZ2luYWwgRXhwZXJpbWVudHMNCg0KIyMjIE9tbmlidXMgUGxvdCBmb3IgQU5HTEVTDQpOb3RlOiBCbHVlcyA9IEFjY2VsZXJhdGlvbiBQZXJ0dXJiYXRpb25zDQpgYGB7cn0NCiMgcmVzdCBvZiB0aGUgZXhwcw0KZGF0YV9wZXJfZ3JvdXAgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKGV4cF9sYWJlbCA9PSAib3JpZ2luYWxfZXhwcyIpICU+JQ0KICBncm91cF9ieShleHBlcmltZW50LCB0ZXN0X3R5cGUsIHRyaWFsX251bSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX2RldmlhdGlvbiA9IG1lYW4odGhyb3dfZGV2aWF0aW9uKSwNCiAgICBjaV9kZXZpYXRpb24gPSB2ZWN0b3JfY29uZmludCh0aHJvd19kZXZpYXRpb24pLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQojIHNldCB1cCBwbG90DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKA0KICAgICAgeCA9IHRyaWFsX251bSwgeSA9IG1lYW5fZGV2aWF0aW9uLCBjb2xvdXIgPSBleHBlcmltZW50DQogICAgKQ0KICApICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgeCA9ICJUcmlhbCBOdW1iZXIiLA0KICAgIHkgPSAiVGhyb3cgQW5nbGUgKMKwKSINCiAgKQ0KDQojIGFkZCBob3Jpem9udGFsIGxpbmVzDQpwIDwtIHAgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKDAsIC0zMCksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gInNvbGlkIg0KICApICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygtMTUpLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkNCg0KIyBwIDwtIHAgKw0KIyAgIHNjYWxlX3lfY29udGludW91cygNCiMgICAgIGxpbWl0cyA9IGMoLTEwLCAzNSksDQojICAgICBicmVha3MgPSBjKDAsIDE1LCAzMCksDQojICAgICBsYWJlbHMgPSBjKDAsIDE1LCAzMCkNCiMgICApICsNCiMgICBzY2FsZV94X2NvbnRpbnVvdXMoDQojICAgICBsaW1pdHMgPSBjKDAsIDE4MCksDQojICAgICBicmVha3MgPSBjKDAsIDYwLCAxMjAsIDE4MCksDQojICAgICBsYWJlbHMgPSBjKDAsIDYwLCAxMjAsIDE4MCkNCiMgICApDQoNCiMgc2V0IGZvbnQgc2l6ZSB0byAxMQ0KcCA8LSBwICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpKQ0KDQojIGFkZCBjb25maWRlbmNlIGludGVydmFscyBhbmQgZGF0YSBwb2ludHMNCnAgPC0gcCArIGdlb21fcmliYm9uKA0KICBhZXMoDQogICAgeW1pbiA9IG1lYW5fZGV2aWF0aW9uIC0gY2lfZGV2aWF0aW9uLA0KICAgIHltYXggPSBtZWFuX2RldmlhdGlvbiArIGNpX2RldmlhdGlvbiwNCiAgICBmaWxsID0gZXhwZXJpbWVudA0KICApLCBjb2xvdXIgPSBOQSwgYWxwaGEgPSAwLjMNCiAgKSArIGdlb21fbGluZSgpDQoNCiMgc2V0IGNvbG91ciBwYWxldHRlDQpwIDwtIHAgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoDQogIHBhbGxldGVfbGlzdFtbInRpbHRfYyJdXSwgcGFsbGV0ZV9saXN0W1sidGlsdF9uYyJdXSwNCiAgcGFsbGV0ZV9saXN0W1sicm90X2MiXV0sIHBhbGxldGVfbGlzdFtbInJvdF9uYyJdXSwNCiAgcGFsbGV0ZV9saXN0W1sicm90XzE1X2MiXV0sIHBhbGxldGVfbGlzdFtbInJvdF8xNV9uYyJdXQ0KKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKA0KICBwYWxsZXRlX2xpc3RbWyJ0aWx0X2MiXV0sIHBhbGxldGVfbGlzdFtbInRpbHRfbmMiXV0sDQogIHBhbGxldGVfbGlzdFtbInJvdF9jIl1dLCBwYWxsZXRlX2xpc3RbWyJyb3RfbmMiXV0sDQogIHBhbGxldGVfbGlzdFtbInJvdF8xNV9jIl1dLCBwYWxsZXRlX2xpc3RbWyJyb3RfMTVfbmMiXV0NCikpDQoNCg0KIyAjIHNhdmUNCiMgaWYgKHNhdmVfcGxvdHMpIHsNCiMgICBnZ3NhdmUoDQojICAgcCwNCiMgICBmaWxlbmFtZSA9ICIuLi9wbG90cy9wYXBlcl9maWdzL3NyXzMwX3RyYWluaW5nLnBkZiIsIGRldmljZSA9ICJwZGYiLA0KIyAgIGhlaWdodCA9IDQsIHdpZHRoID0gNg0KIyAgICkNCiMgICB9DQoNCmdncGxvdGx5KHApDQoNCiMgcA0KYGBgDQojIyMgVHJpYWwgc2V0cyBvZiBpbnRlcmVzdCBvbmx5DQpOb3RlOiBCbHVlcyA9IEFjY2VsZXJhdGlvbiBQZXJ0dXJiYXRpb25zDQpgYGB7cn0NCiMgZmlsdGVyIG91dCBqdXN0IHRoZSB0cmlhbHMgb2YgaW50ZXJlc3QNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBmaWx0ZXIoDQogICAgdGVzdF90eXBlICE9ICJvdGhlciINCiAgKSANCiMgYWRkIGEgZHVtbXkgY29sdW1uIHdpdGggcmVwZWF0aW5nIHNlcXVlbmNlIA0KIyBOT1RFOiB0aGlzIGNhbid0IGJlIGNvbWJpbmVkIHdpdGggYWJvdmUgc2luY2Ugd2UgYXJlIHVzaW5nIG5yb3cNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX2dyb3VwICU+JSANCiAgbXV0YXRlKGR1bW15X3ggPSByZXAoMToobnJvdyhkYXRhX3Blcl9ncm91cCkvNiksIA0KICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgub3V0ID0gbnJvdyhkYXRhX3Blcl9ncm91cCkpKQ0KDQojIHNldCB1cCBwbG90DQpwIDwtIGRhdGFfcGVyX2dyb3VwICU+JQ0KICBnZ3Bsb3QoDQogICAgYWVzKA0KICAgICAgeCA9IGR1bW15X3gsIHkgPSBtZWFuX2RldmlhdGlvbiwgY29sb3VyID0gZXhwZXJpbWVudA0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHggPSAiVHJpYWwgTnVtYmVyIiwNCiAgICB5ID0gIlRocm93IEFuZ2xlICjCsCkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCAtMzApLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoLTE1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApDQoNCiMgYWRkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCBkYXRhIHBvaW50cw0KZm9yICh1bmlxdWVfdGVzdF90eXBlIGluIHVuaXF1ZShkYXRhX3Blcl9ncm91cCR0ZXN0X3R5cGUpKSB7DQogICMgZ2V0IHRoZSBkYXRhIGZvciB0aGlzIGJsb2NrDQogIHRvX3Bsb3RfZGF0YSA8LSBmaWx0ZXIoZGF0YV9wZXJfZ3JvdXAsIHRlc3RfdHlwZSA9PSB1bmlxdWVfdGVzdF90eXBlKQ0KDQogIHAgPC0gcCArIGdlb21fcmliYm9uKA0KICAgIGRhdGEgPSB0b19wbG90X2RhdGEsDQogICAgYWVzKA0KICAgICAgeW1pbiA9IG1lYW5fZGV2aWF0aW9uIC0gY2lfZGV2aWF0aW9uLA0KICAgICAgeW1heCA9IG1lYW5fZGV2aWF0aW9uICsgY2lfZGV2aWF0aW9uLA0KICAgICAgZmlsbCA9IGV4cGVyaW1lbnQNCiAgICApLCBjb2xvdXIgPSBOQSwgYWxwaGEgPSAwLjMNCiAgICApICsgZ2VvbV9saW5lKA0KICAgICAgZGF0YSA9IHRvX3Bsb3RfZGF0YQ0KICAgICkNCn0NCg0KIyBzZXQgY29sb3VyIHBhbGV0dGUNCnAgPC0gcCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygNCiAgcGFsbGV0ZV9saXN0W1sidGlsdF9jIl1dLCBwYWxsZXRlX2xpc3RbWyJ0aWx0X25jIl1dLA0KICBwYWxsZXRlX2xpc3RbWyJyb3RfYyJdXSwgcGFsbGV0ZV9saXN0W1sicm90X25jIl1dLA0KICBwYWxsZXRlX2xpc3RbWyJyb3RfMTVfYyJdXSwgcGFsbGV0ZV9saXN0W1sicm90XzE1X25jIl1dDQopKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoDQogIHBhbGxldGVfbGlzdFtbInRpbHRfYyJdXSwgcGFsbGV0ZV9saXN0W1sidGlsdF9uYyJdXSwNCiAgcGFsbGV0ZV9saXN0W1sicm90X2MiXV0sIHBhbGxldGVfbGlzdFtbInJvdF9uYyJdXSwNCiAgcGFsbGV0ZV9saXN0W1sicm90XzE1X2MiXV0sIHBhbGxldGVfbGlzdFtbInJvdF8xNV9uYyJdXQ0KKSkNCg0KZ2dwbG90bHkocCkNCmBgYA0KDQoNCiMjIyBQbG90cyBmb3IgRVJST1INCk5vdGU6IEJsdWVzID0gQWNjZWxlcmF0aW9uIFBlcnR1cmJhdGlvbnMNCmBgYHtyfQ0KZ2dwbG90bHkocGxvdF9vcmlnaW5hbF9sZWFybmluZ19jdXJ2ZShvbW5pYnVzX3BhdGgpKQ0KYGBgDQoNCnZpc2libGUgdnMgbm9uLXZpc2libGUgdGlsdCBkb2Vzbid0IGFmZmVjdCB0aGUgMTUtZGVncmVlIHJvdGF0aW9uIGNvbmRpdGlvbi4gQnV0IGFmZmVjdHMgYWxsIG90aGVyIGNvbmRpdGlvbnMuIFNvIDE1LWRlZ3JlZSByb3RhdGlvbg0KDQpOb3RlOiBCbHVlcyA9IEFjY2VsZXJhdGlvbiBQZXJ0dXJiYXRpb25zDQpgYGB7cn0NCmdncGxvdGx5KHBsb3Rfb3JpZ2luYWxfcmVib3VuZChvbW5pYnVzX3BhdGgpKQ0KYGBgDQoNCg0KDQojIEFuaW1hdGVkIFN1cmZhY2UgRm9sbG93LXVwDQoNCiMjIyBPbW5pYnVzIFBsb3QgZm9yIEFOR0xFUw0KYGBge3J9DQojIGlzb2xhdGUgYW5pbWF0ZV9zdXJmYWNlIGV4cA0KZGF0YV9wZXJfZ3JvdXAgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKGV4cF9sYWJlbCA9PSAiYW5pbWF0ZV9zdXJmYWNlIikgJT4lDQogIGdyb3VwX2J5KHByaW9yX2FuaW0sIGJsb2NrX251bSwgdHJpYWxfbnVtX2luX2Jsb2NrLCB0cmlhbF9udW0pICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbl9kZXZpYXRpb24gPSBtZWFuKHRocm93X2RldmlhdGlvbiksDQogICAgY2lfZGV2aWF0aW9uID0gdmVjdG9yX2NvbmZpbnQodGhyb3dfZGV2aWF0aW9uKQ0KICApDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gdHJpYWxfbnVtLCB5ID0gbWVhbl9kZXZpYXRpb24sDQogICAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24NCiAgICApDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgbGFicygNCiAgICB4ID0gIlRyaWFsIE51bWJlciIsDQogICAgeSA9ICJUaHJvdyBBbmdsZSAowrApIg0KICApDQoNCiMgYWRkIGhvcml6b250YWwgbGluZXMNCnAgPC0gcCArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoMCwgLTMwKSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAic29saWQiDQogICkgKw0KICBnZW9tX2hsaW5lKA0KICAgIHlpbnRlcmNlcHQgPSBjKC0xNSksIGxpbmV3aWR0aCA9IDAuNCwNCiAgICBjb2xvdXIgPSAiI0NDQ0NDQyIsIGxpbmV0eXBlID0gImRhc2hlZCINCiAgKQ0KDQojIHAgPC0gcCArDQojICAgc2NhbGVfeV9jb250aW51b3VzKA0KIyAgICAgbGltaXRzID0gYygtMTAsIDM1KSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgMTUsIDMwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgMTUsIDMwKQ0KIyAgICkgKw0KIyAgIHNjYWxlX3hfY29udGludW91cygNCiMgICAgIGxpbWl0cyA9IGMoMCwgMTgwKSwNCiMgICAgIGJyZWFrcyA9IGMoMCwgNjAsIDEyMCwgMTgwKSwNCiMgICAgIGxhYmVscyA9IGMoMCwgNjAsIDEyMCwgMTgwKQ0KIyAgICkNCg0KIyBzZXQgZm9udCBzaXplIHRvIDExDQpwIDwtIHAgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpDQoNCiMgcmVwZWF0IGZvciBwcmlvcl9hbmltID09ICJoYWxmIiwgImZ1bGwiIGFuZCAid2FpdCINCmZvciAodW5pcXVlX3ByaW9yX2FuaW0gaW4gdW5pcXVlKGRhdGFfcGVyX2dyb3VwJHByaW9yX2FuaW0pKSB7DQogICMgZ2V0IHRoZSBkYXRhIGZvciB0aGlzIGJsb2NrDQogIHRvX3Bsb3RfZGF0YSA8LSBmaWx0ZXIoZGF0YV9wZXJfZ3JvdXAsIHByaW9yX2FuaW0gPT0gdW5pcXVlX3ByaW9yX2FuaW0pDQogICMgbG9vcCB0aHJvdWdoIHRoZSB1bmlxdWUgYmxvY2tzIGluIHRvX3Bsb3RfZGF0YQ0KICBmb3IgKGJsb2NrIGluIHVuaXF1ZSh0b19wbG90X2RhdGEkYmxvY2tfbnVtKSkgew0KICAgICMgZ2V0IHRoZSBkYXRhIGZvciB0aGlzIGJsb2NrDQogICAgYmxvY2tfZGF0YSA8LSBmaWx0ZXIodG9fcGxvdF9kYXRhLCBibG9ja19udW0gPT0gYmxvY2spDQogICAgIyBhZGQgdGhlIGRhdGEsIHVzZSB0aGUgcGFsbGV0ZV9saXN0IHRvIGdldCB0aGUgY29sb3VyDQogICAgcCA8LSBwICsgZ2VvbV9yaWJib24oDQogICAgICBkYXRhID0gYmxvY2tfZGF0YSwNCiAgICAgIGFlcyhmaWxsID0gcHJpb3JfYW5pbSksDQogICAgICBjb2xvdXIgPSBOQSwgYWxwaGEgPSAwLjMNCiAgICAgICkgKyBnZW9tX2xpbmUoDQogICAgICBkYXRhID0gYmxvY2tfZGF0YSwNCiAgICAgIGFlcyhjb2xvdXIgPSBwcmlvcl9hbmltKSkNCiAgICANCiAgfQ0KfQ0KDQoNCiMgIyBzYXZlDQojIGlmIChzYXZlX3Bsb3RzKSB7DQojICAgZ2dzYXZlKA0KIyAgIHAsDQojICAgZmlsZW5hbWUgPSAiLi4vcGxvdHMvcGFwZXJfZmlncy9zcl8zMF90cmFpbmluZy5wZGYiLCBkZXZpY2UgPSAicGRmIiwNCiMgICBoZWlnaHQgPSA0LCB3aWR0aCA9IDYNCiMgICApDQojICAgfQ0KDQpnZ3Bsb3RseShwKQ0KIyBwDQpgYGANCg0KIyMgRGlmZmVyZW5jZSBiZXR3ZWVuIGhhbGYgYW5kIGZ1bGwgYW5pbWF0aW9uIHdhc2hvdXQgdHJpYWxzDQpgYGB7cn0NCiMgZmlyc3QsIGlzb2xhdGUgdGhlIGRhdGENCmRhdGEgPC0gb21uaWJ1c19kZiAlPiUNCiAgZmlsdGVyKA0KICAgIGV4cF9sYWJlbCA9PSAiYW5pbWF0ZV9zdXJmYWNlIiwNCiAgICBiYXNlbGluZV9ibG9jayA9PSBGQUxTRSwNCiAgICB0ZXN0X3R5cGUgPT0gIndhc2hvdXRfYW5pbSINCiAgICApDQoNCmRhdGFfcGVyX3BwdCA8LSBkYXRhICU+JQ0KICBncm91cF9ieShwcGlkLCBwcmlvcl9hbmltLCB0cmlhbF9udW1faW5fYmxvY2spICU+JQ0KICBzdW1tYXJpc2UoDQogICAgcHB0X21lYW5fZGV2aWF0aW9uID0gbWVkaWFuKHRocm93X2RldmlhdGlvbiksDQogICAgcHB0X2NpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KHRocm93X2RldmlhdGlvbiksDQogICAgbiA9IG4oKQ0KICApDQoNCmRhdGFfcGVyX2dyb3VwIDwtIGRhdGFfcGVyX3BwdCAlPiUNCiAgZ3JvdXBfYnkocHJpb3JfYW5pbSwgdHJpYWxfbnVtX2luX2Jsb2NrKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW5fZGV2aWF0aW9uID0gbWVhbihwcHRfbWVhbl9kZXZpYXRpb24pLA0KICAgIGNpX2RldmlhdGlvbiA9IHZlY3Rvcl9jb25maW50KHBwdF9tZWFuX2RldmlhdGlvbiksDQogICAgbiA9IHN1bShuKQ0KICApDQoNCiMgc2V0IHVwIHBsb3QNCnAgPC0gZGF0YV9wZXJfZ3JvdXAgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4ID0gdHJpYWxfbnVtX2luX2Jsb2NrLCB5ID0gbWVhbl9kZXZpYXRpb24sDQogICAgICBjb2xvdXIgPSBwcmlvcl9hbmltLCBmaWxsID0gcHJpb3JfYW5pbQ0KICAgICkNCiAgKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHggPSAiVHJpYWwgTnVtYmVyIiwNCiAgICB5ID0gIlRocm93IEFuZ2xlICjCsCkiDQogICkNCg0KIyBhZGQgaG9yaXpvbnRhbCBsaW5lcw0KcCA8LSBwICsNCiAgZ2VvbV9obGluZSgNCiAgICB5aW50ZXJjZXB0ID0gYygwLCAtMzApLCBsaW5ld2lkdGggPSAwLjQsDQogICAgY29sb3VyID0gIiNDQ0NDQ0MiLCBsaW5ldHlwZSA9ICJzb2xpZCINCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgeWludGVyY2VwdCA9IGMoLTE1KSwgbGluZXdpZHRoID0gMC40LA0KICAgIGNvbG91ciA9ICIjQ0NDQ0NDIiwgbGluZXR5cGUgPSAiZGFzaGVkIg0KICApDQoNCiMgYWRkIGRhdGEgcG9pbnRzDQpwIDwtIHAgKyBnZW9tX2JlZXN3YXJtKA0KICBkYXRhID0gZGF0YV9wZXJfcHB0LA0KICBhZXMoeSA9IHBwdF9tZWFuX2RldmlhdGlvbiwgDQogICAgICBjb2xvdXIgPSBwcmlvcl9hbmltKSwNCiAgc2l6ZSA9IDEsIGRvZGdlLndpZHRoID0gMC41DQogICkgKyBnZW9tX3JpYmJvbigNCiAgICBhZXMoDQogICAgICB5bWluID0gbWVhbl9kZXZpYXRpb24gLSBjaV9kZXZpYXRpb24sDQogICAgICB5bWF4ID0gbWVhbl9kZXZpYXRpb24gKyBjaV9kZXZpYXRpb24NCiAgICAgICksDQogICAgY29sb3VyID0gTkEsIGFscGhhID0gMC4zDQogICkgKyBnZW9tX2xpbmUoKQ0KDQpnZ3Bsb3RseShwKQ0KYGBgDQoNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojIyBFTVBUWQ0KYGBgDQoNCg0KIyBEZXByZWNhdGVkIChEb24ndCBSdW4pDQoNCiMjIFN1Y2Nlc3MgbWFuaWZvbGRzDQojIyMgV2l0aG91dCBhbnkgdGlsdHMNCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD0yMH0NCiMgZ2dwbG90bHkocGxvdF9zdWNjZXNzX21hbmlmb2xkX25vX3RpbHQoKSkNCnBsb3Rfc3VjY2Vzc19tYW5pZm9sZF9ub190aWx0KCkNCmBgYA0KDQojIyMgV2l0aCB0aWx0IHByZXNlbnQNCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD0yMH0NCmdncGxvdGx5KHBsb3Rfc3VjY2Vzc19tYW5pZm9sZF90aWx0KCkpDQpgYGANCg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCk5VTEwNCmBgYA0KDQo=